package com.food.restaurantpro.observers;

import java.util.ArrayList;
import java.util.Observable;
import java.util.Observer;

import com.food.restaurantpro.R;
import com.food.restaurantpro.RestaurantApp;
import com.food.restaurantpro.connection.DataHelper;
import com.food.restaurantpro.connection.DataResult;
import com.food.restaurantpro.database.tables.FoodTable;
import com.food.restaurantpro.log.Log;
import com.food.restaurantpro.managingnetwork.ManagingNetwork;
import com.food.restaurantpro.objects.Food;
import com.food.restaurantpro.objects.FoodForUpdate;
import com.food.restaurantpro.utils.Prefs;

public class FoodObserver implements Observer {

	private FoodObserver _me = this;
	private boolean hadRegisterObserver = false;
	private ArrayList<Food> mFoodList;
	private ArrayList<String> mFoodIdList;
	//dung de save ngay-gio update food list
	private Prefs mPref;
	private FoodObserverInterface mFoodObserverInterface;
	
	public FoodObserver(FoodObserverInterface foodObserverInterface) {
		mFoodObserverInterface = foodObserverInterface;
		mPref = new Prefs(RestaurantApp.CURRENT_CONTEXT);
	}
	
	/**
	 * register observer and get food list
	 * Khi lan dau tien vao app thi goi api getAllFoods
	 * Lan thu 2 tro di thi goi api getUpdateFoods
	 */
	public void registerObserver() {
		String dateUpdate = mPref.getStringValue(null, Prefs.KEY_DAY_UPDATE_FOODS);
		String timeUpdate = mPref.getStringValue(null, Prefs.KEY_TIME_UPDATE_FOODS);
		//get all id of foods in database
		mFoodIdList = FoodTable.getAllFoodId();
		//check neu chua co du lieu thi get all promotions after insert to database
		if (mFoodIdList == null || mFoodIdList.size() == 0
				|| dateUpdate == null || dateUpdate.equalsIgnoreCase("")
				|| timeUpdate == null || timeUpdate.equalsIgnoreCase("")) {
			// call api get all promotions
			if (ManagingNetwork.isNetworkAvailable()) {
				// show progress
				hadRegisterObserver = true;
				DataHelper.getInstance().addObserver(_me);
				DataHelper.getInstance().getAllDishs();
			} else {
				// Lan dau tien vao app va khong co network, return null
				mFoodObserverInterface.foodListCallback(null, RestaurantApp.CURRENT_CONTEXT.getString(R.string.NETWORK_ERROR));
			}
		} else {
			// call api update foods
			if (ManagingNetwork.isNetworkAvailable()) {
				// show progress
				hadRegisterObserver = true;
				String strFoodId = "";
				for(int i = 0; i < mFoodIdList.size(); i++) {
					strFoodId += mFoodIdList.get(i) + ",";
				}
				String foodId = strFoodId.substring(0, strFoodId.length()-1);
				
				DataHelper.getInstance().addObserver(_me);
				DataHelper.getInstance().getUpdateDishs(dateUpdate + "%20" + timeUpdate, foodId);
			} else {
				//get all foods in database: offline
				//cai nay da doi lai: chi lay danh sach food duoc thay doi tu server
				mFoodObserverInterface.foodListCallback(mFoodList, null);
			}
		}
	}

	/**
	 * must call this method in onDestroy of Activity which called
	 * registerObserver
	 */
	public void unRegisterObserver() {
		if (hadRegisterObserver) {
			DataHelper.getInstance().deleteObserver(_me);
			hadRegisterObserver = false;
		}
	}

	@SuppressWarnings("unchecked")
	@Override
	public void update(Observable observable, Object data) {
		// close progress
		if (data == null)
			return;
		DataResult result = (DataResult) data;
		switch (result.getMethodName()) {
		case getAllDishs:
			if (result.getErrorCode() != null) {
				// show error mesage
				mFoodObserverInterface.foodListCallback(null, result.getErrorCode().getErrorMessage());
			} else {
				mFoodList = (ArrayList<Food>) result.getData();
				if (mFoodList != null) {
					FoodTable.deleteAll();
					FoodTable.insertListFood(mFoodList);
					//Save ngay-gio update promotions
					String currentDay = mPref.getStringValue(null, Prefs.KEY_CURRENT_DAY);
					String currentTime = mPref.getStringValue(null, Prefs.KEY_CURRENT_TIME);
					if(currentDay != null && currentTime != null) {
						mPref.putStringValue(currentDay, Prefs.KEY_DAY_UPDATE_FOODS);
						mPref.putStringValue(currentTime, Prefs.KEY_TIME_UPDATE_FOODS);
					}
					Log.i("FoodObserver", "update() getAllDishs",
							"currentDay = " + currentDay + ", currentTime = "
									+ currentTime);
					//
					mFoodObserverInterface.foodListCallback(mFoodList, null);
				} else {
					mFoodObserverInterface.foodListCallback(null,	RestaurantApp.CURRENT_CONTEXT.getResources()
									.getString(R.string.SERVER_ERROR));
				}
			}
			unRegisterObserver();
			break;
		case getUpdateDishs:
			if (result.getErrorCode() != null) {
				//get all foods in database
				//cai nay da doi lai: chi lay danh sach food duoc thay doi tu server
				// show error code
				mFoodObserverInterface.foodListCallback(null, result.getErrorCode().getErrorMessage());
			} else {
				FoodForUpdate foodUpdate = (FoodForUpdate) result.getData();
				if (foodUpdate != null) {
					//update database: insert, update, delete after get new list
					ArrayList<Food> foodList = foodUpdate.getFoodList();
					ArrayList<String> foodIdList = foodUpdate.getFoodIdList();
					
					//update
					if(foodList != null) {
						boolean isUpdate = false;
						for(int i = 0; i < foodList.size(); i++) {
							Food food = foodList.get(i);
							isUpdate = false;
							for(int j = 0; j < mFoodIdList.size(); j++) {
								//new id = old id: update
								if(food.getFoodID().equalsIgnoreCase(mFoodIdList.get(j))) {
									FoodTable.updateFoodById(food);
									isUpdate = true;
									break;
								}
							}
							//insert
							if(isUpdate == false) {
								FoodTable.insertFood(food);
							}
						}
					}
					
					//delete proId in database
					if(foodIdList != null) {
						for(int i = 0; i < foodIdList.size(); i++) {
							FoodTable.deleteFoodById(foodIdList.get(i));
						}
					}
					//Save ngay-gio update foods
					String currentDay = mPref.getStringValue(null, Prefs.KEY_CURRENT_DAY);
					String currentTime = mPref.getStringValue(null, Prefs.KEY_CURRENT_TIME);
					if(currentDay != null && currentTime != null) {
						mPref.putStringValue(currentDay, Prefs.KEY_DAY_UPDATE_FOODS);
						mPref.putStringValue(currentTime, Prefs.KEY_TIME_UPDATE_FOODS);
					}
					//
					Log.i("FoodObserver", "update() getUpdateDishs",
							"currentDay = " + currentDay + ", currentTime = "
									+ currentTime);
					//get all foods in database
					//cai nay da doi lai: chi lay danh sach food duoc thay doi tu server
					mFoodObserverInterface.foodListCallback(foodList, null);
				} else {
					//get all foods in database
					//cai nay da doi lai: chi lay danh sach food duoc thay doi tu server
					mFoodObserverInterface.foodListCallback(null, null);
				}
			}
			unRegisterObserver();
			break;
		default:
			break;
		}
		// Chu y: Observer se post notification den tat ca cac lop da register
		// observer. Va cho nao co phuong thuc trung voi phuong thuc no tra ve thi xu ly
		// cho do, nhung cho khac ko xu ly, vi vay PHAI dat code o trong "case method:"
		//khong dat code o ngoai nay
	}

}
